package com.woniu.his.sms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.his.exception.HisException;
import com.woniu.his.result.CommonResultCode;
import com.woniu.his.sms.common.SmsResultCode;

import com.woniu.his.sms.common.enums.SmsStatusEnums;
import com.woniu.his.sms.infra.model.*;
import com.woniu.his.sms.infra.mapper.StaffMapper;
import com.woniu.his.sms.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.his.sms.service.dto.*;
import com.woniu.his.sms.service.param.PageStaffServerParam;
import com.woniu.his.sms.service.param.StaffLoginServerParam;
import com.woniu.his.sms.service.param.StaffUpdateServerParam;
import com.woniu.his.sms.service.param.SmsSkdDocServiceParam;
import com.woniu.his.sms.service.param.StaffPwdSeParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

import javax.annotation.Resource;
import java.util.stream.Collectors;

/**
 * <p>
 * 员工表 服务实现类
 * </p>
 *
 * @author cb
 * @since 2022-11-25
 */
@Service
@Slf4j
public class StaffServiceImpl extends ServiceImpl<StaffMapper, Staff> implements StaffService {

    @Resource
    private DeptService deptService;

    @Resource
    private SkdService skdService;

    @Resource
    private RegistrationRankService registrationRankService;

    @Resource
    private RoleService roleService;

    @Resource
    private PermissionService permissionService;


    /**
     * @Description: 根据日期查询上班医生符合挂号级别
     * @Param:
     * @return: dx
     * @Date: 2022/11/25
     */
    @Override
    public List<StaffServiceDto> listDocBySkd(SmsSkdDocServiceParam smsSkdDocServiceParam) {

        //判断日期是否在当天以后

//        System.out.println(smsSkdDocServiceParam.getDate());
//        System.out.println(smsSkdDocServiceParam.getDate().getTime());
//        System.out.println( getStartDateTime().getTime());
//        System.out.println(getStartDateTime());
//        System.out.println(Math.floor((getStartDateTime().getTime())/10000)*10000 );
        if (smsSkdDocServiceParam.getDate().getTime() <Math.floor((getStartDateTime().getTime())/10000)*10000 ) {
            throw new HisException(SmsResultCode.REGISTRATION_DATE_ERROR);
        }

        //判断科室id是否存在
        if (deptService.getById(smsSkdDocServiceParam.getDeptId()) == null) {
            throw new HisException(SmsResultCode.DEPT_NOT_EXIST);
        }

        //通过排班表查出符合日期科室的排班表
        List<Skd> list = skdService.list(new QueryWrapper<Skd>().eq("dept_id", smsSkdDocServiceParam.getDeptId())
                .eq("noon", smsSkdDocServiceParam.getNoon()).eq("date", smsSkdDocServiceParam.getDate()));
        System.out.println(skdService.list(new QueryWrapper<Skd>().eq("date", smsSkdDocServiceParam.getDate())));
        System.out.println(list.toString());

        //获取符合挂号等级的排班id
        List<Long> skids = list.stream().filter(o -> {
            return getById(o.getStaffId()).getRegistrationRankId().equals(smsSkdDocServiceParam.getRegistrationRankId());
        }).map(Skd::getId).collect(Collectors.toList());

        System.out.println(skids.toString());
        if (skids.isEmpty()) throw new HisException(SmsResultCode.SKD_NOT_MATCH);
        //新建返回参数
        List<StaffServiceDto> returnList = new ArrayList<>();
        for (Long skid : skids) {
            StaffServiceDto staffResult = new StaffServiceDto();
            staffResult.setSkdId(skid);
            Staff staff = getById(skdService.getById(skid).getStaffId());
            staffResult.setName(staff.getStaffName());
            staffResult.setAmount(registrationRankService.getById(staff.getRegistrationRankId()).getPrice());
            returnList.add(staffResult);
        }
        return returnList;
    }


    private  Date getStartDateTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }


    /**
     * @Description: 根据用户密码查找用户
     * @Param:
     * @return:
     * @Date: 2022/11/26
     */
    @Override
    public loginStaffServiceDto findStaffByPwd(StaffPwdSeParam staffPwdSeParam) {
        Staff staff = getOne(new QueryWrapper<Staff>().eq("staff_password", staffPwdSeParam.getStaffPassword()).
                eq("username", staffPwdSeParam.getUsername()));
        if (staff == null) {
            throw new HisException(SmsResultCode.LOGIN_PASS_NAME_WRONG);
        }
        return BeanUtil.copyProperties(staff, loginStaffServiceDto.class);
    }


    /**
     * @Description: 根据员工id查询登录员工
     * @Param:
     * @return:
     * @Date: 2022/11/26
     */
    @Override
    public loginStaffServiceDto findLoginStaffById(Integer staffId) {
        Staff staff = getById(staffId);
        if (staff == null) {
            throw new HisException(SmsResultCode.LOGIN_RESULT_CODE);
        }
        System.out.println(staff);

        if (!staff.getStaffStatus().equals("AVAILABLE")) {
            throw new HisException(SmsResultCode.LOGIN_RESULT_CODE);
        }
        return BeanUtil.copyProperties(staff, loginStaffServiceDto.class);
    }

    /**
     * @Description: 根据员工ids删除用户
     * @Param:
     * @return:
     * @Date: 2022/11/26
     */
    @Override
    public boolean deleteStaff(List<Long> ids) {
        for (Long id : ids) {
            if (getById(id).getStaffStatus().equals("DELETE")) {
                throw new HisException(SmsResultCode.STAFF_DELETED);
            }
            //查询员工是否在排班中，排班中不能删除
            Date date = new Date(86400000L * (int)(System.currentTimeMillis() / 86400000.0)-1000*60*60*8);
            if (skdService.list(new QueryWrapper<Skd>().eq("staff_id", id).
                    ge("date", date)).size() >= 1) {
                throw new HisException(SmsResultCode.DOCTOR_IS_ABOUT_TO_WORK);
            }
        }
        for (Long id : ids) {
            Staff staff = getById(id);
            staff.setStaffStatus("DELETE");
            updateById(staff);
        }
        return true;
    }

    @Override
    public List<StaffInfoDto> findAllStaffByDeptId(Integer deptId) {
        Dept one = deptService.getById(deptId);
        if (one == null) throw new HisException(SmsResultCode.DEPT_NOT_EXIST);
        QueryWrapper<Staff> wrapper = new QueryWrapper<>();
        wrapper.eq("dept_id", deptId).eq("staff_status", SmsStatusEnums.AVAILABLE);
        List<Staff> list = list(wrapper);
        if (list.size() <= 0) return null;
        List<StaffInfoDto> staffInfoDtos = BeanUtil.copyToList(list, StaffInfoDto.class);
        for (StaffInfoDto staffInfoDto : staffInfoDtos) {
            staffInfoDto.setDeptName(one.getDeptName());
        }
        return staffInfoDtos;
    }

    /**
     * 查询全部用户
     *
     * @return
     */
    @Override
    public List<StaffAllDto> queryAll() {
        QueryWrapper<Staff> wrapper = new QueryWrapper<>();
        wrapper.eq("staff_status", "AVAILABLE");
        List<Staff> list = list(wrapper);
        if (list == null) return null;
        List<StaffAllDto> staffAllDtos = BeanUtil.copyToList(list, StaffAllDto.class);
        return staffAllDtos;
    }

    /**
     * 模糊查询用户 且分页
     *
     * @param param
     * @return
     */
    @Override
    public PageStaffDto QueryPageStaff(PageStaffServerParam param) {
        QueryWrapper<Staff> wrapper = new QueryWrapper<>();
        wrapper.eq("staff_status", "AVAILABLE");
        if (param.getStaffName() != null) wrapper.like("staff_name", param.getStaffName());
        if (param.getTitle() != null) wrapper.like("title", param.getTitle());
        IPage<Staff> page = page(new Page<Staff>(param.getIndexPage()==null?1: param.getIndexPage(), param.getPageSize()==null?5: param.getPageSize()), wrapper);

        PageStaffDto pageStaffDto = new PageStaffDto();
        pageStaffDto.setPageSize(page.getCurrent());
        pageStaffDto.setTotal(page.getTotal());

        //这里就不对了

        List<StaffAllDto> staffAllDtos = BeanUtil.copyToList(page.getRecords(), StaffAllDto.class);

        pageStaffDto.setStaffList(staffAllDtos);
        return pageStaffDto;
    }

    /**
     * 修改用户信息
     *
     * @param updateServerParam
     * @return
     */
    @Override
    public Integer UpdateStaff(StaffUpdateServerParam updateServerParam) {
        //判断科室id是否存在以及可不可以使用
        Dept byId = deptService.getById(updateServerParam.getDeptId());
        if ( byId== null ||byId.getDeptStatus().equals("OFF")) {
            throw new HisException("科室不存在 或者不可以使用",2001);
        }

        //判断挂号等级是否存在以及可不可以使用
        RegistrationRank byId1 = registrationRankService.getById(updateServerParam.getRegistrationRankId());
        if(byId == null || byId.getDeptStatus().equals("OFF")){
            throw new HisException("挂号等级不存在 或者不可以使用",2001);
        }
        //判断角色是否存在 是否可以使用
            Role byId2 = roleService.getById(updateServerParam.getRoleId());
            if(byId2 == null || byId2.getRoleStatus().equals("OFF")){
                throw new HisException("角色等级不存在 或者不可以使用",2001);
            }
            Staff staff = BeanUtil.copyProperties(updateServerParam, Staff.class);
            boolean b = updateById(staff);
            return b ? 1 : 0;
    }

    /**
     * 用户登录
     *
     * @param serverParam
     * @return
     */
    @Override
    public Map login(StaffLoginServerParam serverParam) {
        QueryWrapper<Staff> wrapper = new QueryWrapper<>();
        wrapper.eq("username", serverParam.getUsername());
        Staff one = getOne(wrapper);
        if (one == null || !one.getStaffStatus().equals("AVAILABLE")) {
            throw new HisException(SmsResultCode.LOGIN_RESULT_CODE);
        }
        if (!one.getStaffPassword().equals(serverParam.getStaffPassword())) {
            throw new HisException(SmsResultCode.LOGIN_PassSMS_RESULT_CODE);
        }
        List<String> url = permissionService.getUrl(one.getId());
        Map<String, Object> map = new HashMap<>();
        map.put("userName", one.getUsername());
        map.put("staffId", one.getId());
        map.put("urls",url);
        return map;
    }
}
